// LemCoop
// Copyright (C) 2013  Oliver Naumann <bldrax@gmail.com>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#ifndef LEMC_LEVELSTATE_H
#define LEMC_LEVELSTATE_H

#include <WindowsIncludes.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <allegro5/allegro_primitives.h>
#include <MessageIdentifiers.h>
#include <StringCompressor.h>

#include "../system/gameengine.h"
#include "gamestate.h"
#include "../util/helpers.h"
#include "../network/clientconnectionlist.h"
#include "../network/clientconnection.h"
#include "../network/raknetserver.h"
#include "../network/raknetclient.h"
#include "../network/workmanager.h"
#include "../network/job.h"
#include "../level/level.h"
#include "../lem/lem.h"
#include "../lem/lemcollection.h"

class LevelState : public GameState
{
private:
	bool m_is_server;
	RakNetServer* m_server;
	RakNetClient* m_client;
	std::string m_guid;
	WorkManager* m_work_manager;

	Level* m_level;
	float m_time_running;
	bool m_opened;
	bool m_release_started;

	// The lems.
	LemCollection m_lems;

	// The list of connected clients.
	ClientConnectionList m_client_list;
	bool m_shutdown_network_on_state_end;

	void ServerInit();
	void ClientInit();
	void ServerCleanup();
	void ClientCleanup();

	void DoServerWork();
	void DoClientWork();
	
	void ServerRemovePlayer(std::string guid);
	void ServerKickPlayer(std::string guid);

	void ClientProcessClosedConnection();
	void ClientProcessRemoveClient(Job remove_client_job);
	void ClientProcessOpenEntries();
	void ClientProcessStartSpawn();

	void ServerUpdate(float timing_factor);
	void ClientUpdate(float timing_factor);

public:
	LevelState(GameEngine* engine);
	~LevelState();

	void Init(bool is_server, RakNetServer* m_server, RakNetClient* m_client, ClientConnectionList client_list,
		Level* level);
	void HandleInput(ALLEGRO_EVENT next_event);
	void Update(float timing_factor);
	void Draw();
};

#endif